[FEATURE] Support :lines: in literalinclude - #1352
Conversation
23bcfbc to
5e05cbe
Compare
`literalinclude` always included the complete referenced file. Authors who want to show one relevant region of a real source or configuration file had to duplicate that region into a dedicated snippet file, which then silently drifts away from the original. Add the Sphinx options `:start-after:` and `:end-before:`. The included region starts on the line following the first line containing the `start-after` text and ends on the line preceding the first line containing the `end-before` text. `end-before` is searched behind the start of the region, so the same marker text may be used more than once in a file. Markers are stable against edits outside the marked region, unlike line numbers. Nothing is included, and a warning names the reason, when a marker is not found, when an option is used without a value, when `end-before` occurs only above the line matched by `start-after`, and when the marked region is empty. Falling back to the complete file in those cases would publish exactly the content the option was meant to exclude. The selection happens before the CodeNode is created, so it stays in the directive rather than in DefaultCodeNodeOptionMapper, which is shared with `code-block` and only maps display options. The logger is an optional constructor argument, as in ConfvalDirective, so that adding it does not break consumers that build the directive themselves. Assisted-by: claude-code:claude-opus-5 Agent-Session: https://claude.ai/code/session_015QXXkquh2eQNBiTYA39Wss Signed-off-by: Sebastian Mendel <sebastian.mendel@netresearch.de>
The reference section had no page for `literalinclude`, so neither the directive itself nor its options were documented anywhere. Add one, covering the directive, the new `:start-after:` and `:end-before:` options, and the options the shared code node option mapper provides. Every documented behaviour was rendered and read back before being written down, including what happens when the file is missing (error, nothing rendered) and when a marker is not found (warning, nothing included). Assisted-by: claude-code:claude-opus-5 Agent-Session: https://claude.ai/code/session_015QXXkquh2eQNBiTYA39Wss Signed-off-by: Sebastian Mendel <sebastian.mendel@netresearch.de>
Add the Sphinx option `:lines:` to `literalinclude`, so a region can also be selected by line number, for example `:lines: 1,3-5,20-`. Line numbers are 1 based, ranges are inclusive, an omitted end means "up to the last line", and overlapping ranges are included once, in document order. The accepted spelling is the one already used by `:emphasize-lines:`, so both options are written the same way. Like Sphinx, `:lines:` is applied after `:start-after:` and `:end-before:`, therefore the numbers count within the marked region rather than within the file. Markers stay the more robust choice, because line numbers break on every edit above the selected region. Both ends of a range are clamped to the lines that exist, so a range far beyond the end of the file selects nothing instead of iterating over the numbers the author wrote down. Each range that selects no line is warned about on its own, naming the range, while the remaining ranges are still included. A missing value, or a value that is not a list of line numbers, logs a warning and includes nothing. Assisted-by: claude-code:claude-opus-5 Agent-Session: https://claude.ai/code/session_015QXXkquh2eQNBiTYA39Wss Signed-off-by: Sebastian Mendel <sebastian.mendel@netresearch.de>
Add the `:lines:` option to the reference page: syntax, that overlapping ranges are included once in the order of the file, that it is applied after the markers and therefore counts within the marked region, and what happens when the value selects nothing. Each of these was rendered and read back before being written down. Assisted-by: claude-code:claude-opus-5 Agent-Session: https://claude.ai/code/session_015QXXkquh2eQNBiTYA39Wss Signed-off-by: Sebastian Mendel <sebastian.mendel@netresearch.de>
5e05cbe to
58c3589
Compare
|
Coverage gap: there are existing tests for |
|
|
Builds on #1351 and contains its two commits, so only the last two commits are new here — see the commit list. Please review #1351 first; I will rebase this one onto
mainonce that is merged.What this adds
The Sphinx option
:lines:forliteralinclude, so a region can also be selected by line number:Line numbers are 1 based, ranges are inclusive, an omitted end means "up to the last line", and overlapping ranges are included once, in document order. Both ends are clamped to the lines that exist, so
:lines: 1-99999999999selects the whole region instead of iterating over the number the author wrote down.The accepted spelling is validated with
DefaultCodeNodeOptionMapper::LINE_NUMBER_RANGES_REGEX, the pattern already used for:emphasize-lines:, so both options are written the same way. If you would rather not have the directive reference the mapper's constant, say so and I will move the pattern to a shared place.Order of application
Like Sphinx,
:lines:is applied after:start-after:and:end-before:, so the numbers count within the marked region rather than within the file. There is an integration test for that combination.I would still describe markers as the more valuable half of this: line numbers break on every edit above the selected region, markers do not.
:lines:is here for Sphinx compatibility and for files that have no natural marker.Behaviour on an invalid or empty selection
Each range that selects no line is warned about on its own, naming that range, and the remaining ranges are still included —
:lines: 1-2,100on a 15 line file includes lines 1 and 2 and says that100selected nothing. A missing value or a value that is not a list of line numbers logs a warning and includes nothing, consistent with a marker that is not found in #1351.Documentation
The reference page added in #1351 gets a section on selecting lines by number, including the order of application and the advice to prefer markers where a file has them.
Tests
Eight integration tests: a mixed range list, an open ended range, an invalid specification, a range beyond the end of the file, a range list where only one entry is beyond the end,
:lines:used without a value, a range far beyondPHP_INT_MAXterritory as a regression test for the clamping, and:lines:combined with markers.Local run of
phpunit(unit, functional, integration),phpcs,phpstananddeptrac: green.Assisted by claude-code:claude-opus-5 — Session